package com.xmqsfsky1017.skysrf.utils;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import java.util.*;
import java.lang.RuntimeException;

public class Table {
	
	public static class TableException extends RuntimeException {
		public TableException(String message) {
			super(message);
		}
	}
	
	private String[] attrNames;
	private Class[] dataTypes;
	private HashMap<String, Object[]> data;
	
	public Table(String[] attrNames, Class[] dataTypes) {
		if (attrNames == null || dataTypes == null) {
			throw new TableException("属性名或数据类型不能为null");
		}
		
		if (attrNames.length != dataTypes.length) {
			throw new TableException("表格列数与其类型数量不匹配哦");
		}
		this.attrNames = attrNames;
		this.dataTypes = dataTypes;
		this.data = new HashMap<String, Object[]>();
	}
	
	public Table(Class dataType,String[] attrNames){
		if (attrNames == null || dataType == null) {
			throw new TableException("属性名或数据类型不能为null");
		}
		
		Class[] dataTypes = new Class[attrNames.length];
		for (int i=0;i<attrNames.length;i++){
			dataTypes[i] = dataType;
		}
		this.attrNames = attrNames;
		this.dataTypes = dataTypes;
		this.data = new HashMap<String, Object[]>();
	}
	
	public static boolean isEq(Object o1, Object o2) {
		if (o1 == o2) {
			return true;
		}
		if (o1 == null || o2 == null) {
			return false;
		}
		return o1.equals(o2);
	}
	
	static private int getIndex(Object[] lst, Object obj) {
		if (lst == null) {
			throw new Table.TableException("列表不能为 null");
		}
		for (int i = 0; i < lst.length; i++) {
			if (Table.isEq(lst[i], obj)) {
				return i;
			}
		}
		return -1;
	}
	
	public void setLine(String linename, Object... datas) {
		if (datas.length != this.attrNames.length) {
			throw new TableException("字段和值不对应");
		}
		
		for (int i = 0; i < this.attrNames.length; i++) {
			if (datas[i] != null) {
				Class needingClass = this.dataTypes[i];
				Class givingClass = datas[i].getClass();
				if (datas[i] != null && !needingClass.isInstance(datas[i])) {
					throw new TableException(String.format("表格行%s的字段%s的数据类型不符", linename, this.attrNames[i]));
				}
			}
		}
		this.data.put(linename, datas);
	}
	
	public Object[] getLine(String linename) {
		if (this.data.containsKey(linename)) {
			return this.data.get(linename).clone();
		}
		return null;
	}
	
	public Object getItem(String linename, String attrName) {
		Object[] line;
		if (this.data.containsKey(linename)) {
			line = this.data.get(linename);
			} else {
			return null;
		}
		if (Table.getIndex(this.attrNames, attrName) != -1) {
			return line[Table.getIndex(attrNames, attrName)];
		}
		return null;
	}
	
	// 新增方法
	public Set<String> getAllLineNames() {
		return Collections.unmodifiableSet(data.keySet());
	}
	
	public void removeLine(String linename) {
		data.remove(linename);
	}
	
	public boolean containsLine(String linename) {
		return data.containsKey(linename);
	}
	
	public int getColumnCount() {
		return attrNames.length;
	}
	
	public String[] getAttributeNames() {
		return attrNames.clone();
	}
	
	public Class[] getDataTypes() {
		return dataTypes.clone();
	}
	
	public void clear() {
		data.clear();
	}
	
	public int size() {
		return data.size();
	}
	
	public void setItem(String linename, String attrName, Object value) {
		int index = getIndex(attrNames, attrName);
		if (index == -1) {
			throw new TableException("属性名不存在");
		}
		if (value != null && !dataTypes[index].isInstance(value)) {
			throw new TableException("数据类型不符");
		}
		Object[] line = data.get(linename);
		if (line == null) {
			throw new TableException("行不存在");
		}
		line[index] = value;
	}
	
	public String toString() {
        JsonObject json = new JsonObject();
        
        // 添加列名数组
        JsonArray columns = new JsonArray();
        for (String name : attrNames) {
            columns.add(name);
        }
        json.add("columns", columns);

        // 添加行数据（所有值转为字符串）
        JsonObject dataObj = new JsonObject();
        for (String lineName : data.keySet()) {
            JsonArray values = new JsonArray();
            for (Object val : data.get(lineName)) {
                values.add(val != null ? val.toString() : null);
            }
            dataObj.add(lineName, values);
        }
        json.add("data", dataObj);

        return new Gson().toJson(json);
    }

   public static Table load(String json) {
    try {
        Gson gson = new Gson();
        // 解析 JSON 为临时结构（匹配 toString 生成的格式）
        JsonObject root = gson.fromJson(json, JsonObject.class);

        // 解析表头（columns 数组 -> String[]）
        JsonArray columnsArray = root.getAsJsonArray("columns");
        String[] attrNames = new String[columnsArray.size()];
        for (int i = 0; i < columnsArray.size(); i++) {
            attrNames[i] = columnsArray.get(i).getAsString();
        }

        // 所有单元格均为字符串类型，因此数据类型数组全为 String.class
        Class[] dataTypes = new Class[attrNames.length];
        Arrays.fill(dataTypes, String.class);

        // 创建 Table 对象（使用 String 类型的构造方法）
        Table table = new Table(attrNames, dataTypes);

        // 解析数据行（data 对象 -> 行名 -> 字段数组）
        JsonObject dataObj = root.getAsJsonObject("data");
        for (Map.Entry<String, JsonElement> entry : dataObj.entrySet()) {
            String linename = entry.getKey(); // 行名
            JsonArray valuesArray = entry.getValue().getAsJsonArray(); // 字段数组

            // 转换为 Object[]（所有值为字符串）
            Object[] values = new Object[valuesArray.size()];
            for (int i = 0; i < valuesArray.size(); i++) {
                // 若 JSON 中是 null，则保持 null；否则转为字符串
                values[i] = valuesArray.get(i).isJsonNull() ? null : valuesArray.get(i).getAsString();
            }

            // 添加到表格（检查类型匹配，这里全为 String，符合 dataTypes）
            table.setLine(linename, values);
        }

        return table;
    } catch (Exception e) {
        throw new TableException("解析 JSON 失败：" + e.getMessage());
    }
}
}


